import 'dart:math';

import 'package:word_game/battle/attack_action.dart';
import 'package:word_game/battle/skills/buff.dart';
import 'package:word_game/engine/core.dart';
import 'role_action.dart';
import 'skills/debuff.dart';

mixin Battleable on Living {
  /// 数值越小优先级越高
  int attackPriority = 5;
  /// 暴击率，默认10%
  int critRate = 10;
  /// 暴击伤害倍数
  int critMultiple = 2;

  List<Debuff> debuffs = [];
  List<Buff> buffs = [];

  /// 是否可以行动，用来判断被禁情况，默认true
  /// 若存在禁止攻击的debuff则返回false
  bool canDoAction(int round) {
    for (var item in debuffs) {
      if (item.noAttack) {
        return false;
      }
    }
    return true;
  }

  /// 确定该回合使用什么动作，默认普通攻击
  RoleAction determineAction(int round) {
    AttackAction action = AttackAction();
    action.attackNumber = finalAttackPower();
    int value = Random.secure().nextInt(100);
    if (value <= finalCritRate()) {
      action.critMultiple = critMultiple;
    }
    return action;
  }

  int finalAttackPower() {
    int result = attackPower;
    for (var buff in buffs) {
      result += buff.attackPowerIncrement;
    }
    for (var debuff in debuffs) {
      result -= debuff.attackPowerDecrement;
    }
    // 强制扣1血
    return result<1 ? 1 : result;
  }

  int finalCritRate() {
    int result = critRate;
    for (var buff in buffs) {
      result += buff.critRateIncrement;
    }
    return result;
  }

  /// 普通攻击，默认随机攻击一个目标
  List<Battleable> determineNormalAttackTargets(List<Battleable> alternatives) {
    if (alternatives == null || alternatives.length == 0) {
      return [];
    }
    int index = Random.secure().nextInt(alternatives.length);
    return [alternatives[index]];
  }

  /// 执行受到的攻击动作
  AttackResult performAttackAction(AttackAction action) {
    var damageNumber = action.attackNumber * action.critMultiple;
    this.vitality -= damageNumber;
    AttackResult result = AttackResult();
    if (action.critMultiple > 1) {
      result.reason = '被暴击，受到${damageNumber}点伤害';
    } else {
      result.reason = '受到${damageNumber}点伤害';
    }
    return result;
  }

  /// 执行受到的治疗动作
  /// return: 实际治疗量
  int performHealAction(int healNumber) {
    this.vitality += healNumber;
    return healNumber;
  }

}